/*
 * MIT License
 *
 * Copyright (c) 2018 Alibaba Group
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.tmall.wireless.vaf.virtualview.container;

import com.tmall.wireless.vaf.Log;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Canvas;
import ohos.app.Context;
import com.tmall.wireless.vaf.framework.cm.ContainerService;
import com.tmall.wireless.vaf.virtualview.core.IContainer;
import com.tmall.wireless.vaf.virtualview.core.IView;
import com.tmall.wireless.vaf.virtualview.core.Layout;
import com.tmall.wireless.vaf.virtualview.core.ViewBase;
import com.tmall.wireless.vaf.virtualview.view.nlayout.INativeLayoutImpl;

import java.util.List;

/**
 * Created by gujicheng on 16/8/16.
 */
public class Container extends ComponentContainer implements IContainer, IView, Component.DrawTask, Component.EstimateSizeListener, ComponentContainer.ArrangeListener {
    private final static String TAG = "Container_TMTEST";

    protected ViewBase mView;

    public Container(Context context) {
        super(context);
        addDrawTask( this, DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
        setEstimateSizeListener(this);
        setArrangeListener(this);
    }

    @Override
    public void destroy() {
        mView.destroy();
        mView = null;
    }

    @Override
    public int getType() {
        return ContainerService.CONTAINER_TYPE_NORMAL;
    }

    @Override
    public void attachViews() {
        attachViews(mView, this);
    }

    protected void attachViews(ViewBase view, Component displayViewHolder) {
        view.setDisplayViewContainer(displayViewHolder);
        if (view instanceof Layout) {
            Log.i("Container.attachViews:75     layout:" + view);
            Component v = view.getNativeView();
            if (null != v) {
                if (v.getComponentParent() == null) {
                    LayoutConfig layoutParams = new LayoutConfig(view.getComLayoutParams().mLayoutWidth, view.getComLayoutParams().mLayoutHeight);
                    addComponent(v, layoutParams);
                } else {
                    LayoutConfig layoutParams = v.getLayoutConfig();
                    layoutParams.width = view.getComLayoutParams().mLayoutWidth;
                    layoutParams.height = view.getComLayoutParams().mLayoutHeight;
                    v.setLayoutConfig(layoutParams);
                }


                if (v instanceof INativeLayoutImpl) {
                    Layout layout = (Layout) view;
                    List<ViewBase> subViews = layout.getSubViews();
                    if (null != subViews) {
                        for (int i = 0, size = subViews.size(); i < size; i++) {
                            ViewBase com = subViews.get(i);
                            ((INativeLayoutImpl) v).attachViews(com, v);
                        }
                    }
                }
            } else {
                Layout layout = (Layout) view;
                List<ViewBase> subViews = layout.getSubViews();
                if (null != subViews) {
                    for (int i = 0, size = subViews.size(); i < size; i++) {
                        ViewBase com = subViews.get(i);
                        attachViews(com, displayViewHolder);
                    }
                }
            }
        } else {
            Component v = view.getNativeView();
            Log.i("Container.attachViews:75     child:" + view);
            if (null != v) {
                if (v.getComponentParent() == null) {
                    LayoutConfig layoutParams = new LayoutConfig(view.getComLayoutParams().mLayoutWidth, view.getComLayoutParams().mLayoutHeight);
                    addComponent(v, layoutParams);
                } else {
                    LayoutConfig layoutParams = v.getLayoutConfig();
                    layoutParams.width = view.getComLayoutParams().mLayoutWidth;
                    layoutParams.height = view.getComLayoutParams().mLayoutHeight;
                    v.setLayoutConfig(layoutParams);
                }
            }

        }
    }

    @Override
    public void setVirtualView(ViewBase l) {
        if (null != l) {
            mView = l;
            mView.setHoldView(this);

            //TODO 如果一个View不需要绘制任何内容，那么设置这个标记为true后，系统会进行相应的优化  修改
//            if (mView.shouldDraw()) {
//                setWillNotDraw(false);
//            }

            new ClickHelper(this);
        }
    }

    public void detachViews() {
//        this.removeAllViews();
        //TODO 修改
        this.removeAllComponents();
    }

    @Override
    public ViewBase getVirtualView() {
        return mView;
    }

    @Override
    public Component getHolderView() {
        return this;
    }

    //TODO 修改至初始化时添加的监听中
//    @Override
//    protected void onDraw(Canvas canvas) {
//        if (null != mView && mView.shouldDraw()) {
//            mView.comDraw(canvas);
//        }
//    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        if (null != mView && mView.shouldDraw()) {
            mView.comDraw(canvas);
        }
    }

    @Override
    public void measureComponent(int widthMeasureSpec, int heightMeasureSpec) {
        if (null != mView) {
            if (!mView.isGone()) {
                mView.measureComponent(widthMeasureSpec, heightMeasureSpec);
            }
//            this.setMeasuredDimension(mView.getComMeasuredWidth(), mView.getComMeasuredHeight());//TODO 修改
            this.setEstimatedSize(mView.getComMeasuredWidth(), mView.getComMeasuredHeight());
        }
    }

    @Override
    public void comLayout(int l, int t, int r, int b) {
        if (null != mView && !mView.isGone()) {
            mView.comLayout(0, 0, r - l, b - t);
//            this.layout(l, t, r, b);//TODO　修改
            this.arrange(l, t, r, b);
        }
    }

    @Override
    public void arrange(int left, int top, int width, int height) {
        Log.i("Container.arrange([left, top, width, height]):194");
        super.arrange(left, top, width, height);
    }

    @Override
    public void onComMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (null != mView) {
            if (!mView.isGone()) {
                mView.onComMeasure(widthMeasureSpec, heightMeasureSpec);
            }

//            setMeasuredDimension(mView.getComMeasuredWidth(), mView.getComMeasuredHeight());//TODO 修改
            setEstimatedSize(mView.getComMeasuredWidth(), mView.getComMeasuredHeight());
            Log.i("Container.NativeLineImp.onDraw([widthMeasureSpec, heightMeasureSpec]):203       " + mView + "        " + mView.getComMeasuredWidth() + "   " + mView.getComMeasuredHeight());
        }
    }

    @Override
    public void onComLayout(boolean changed, int l, int t, int r, int b) {
        if (null != mView && !mView.isGone()) {
            mView.onComLayout(changed, l, t, r, b);
        }
    }

    @Override
    public int getComMeasuredWidth() {
        if (null != mView) {
            return mView.getComMeasuredWidth();
        } else {
            return 0;
        }
    }

    @Override
    public int getComMeasuredHeight() {
        if (null != mView) {
            return mView.getComMeasuredHeight();
        } else {
            return 0;
        }
    }


    //TODO
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        onComMeasure(widthMeasureSpec, heightMeasureSpec);
//    }
//
    @Override
    public boolean onEstimateSize(int widthMeasureSpec, int heightMeasureSpec) {
        onComMeasure(widthMeasureSpec, heightMeasureSpec);
        return true;
    }
//    @Override
//    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        onComLayout(changed, 0, 0, r - l, b - t);
//    }

    @Override
    public boolean onArrange(int l, int t, int r, int b) {
        onComLayout(true, l, t, r, b);
        return onArrageTag;
    }

    boolean onArrageTag = false;

    public void setNeedOnArrange(boolean onArrageTag) {
        this.onArrageTag = onArrageTag;
    }
}
